import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Vector;
import java.io.*;

import soot.PackManager;
import soot.Transform;

public class PathGenerator {

	private static Vector<String> files;
	private static String runClass;
	private static String startClass;
	private static String startLine;
	private static String endClass;
	private static String endLine;

	public static void main(String[] args) {
		try {
			// read and parse arguments from a local file.
			Scanner arg = new Scanner(new File(DirectoryUtil.ARGUMENT_PATH));
			Vector<String> argsContainer = new Vector<String>();
			while (arg.hasNext()) {
				argsContainer.add(arg.nextLine());
			}
			if (argsContainer.size() != 3) {
				System.err.println("please check your config file.");
				System.exit(0);
			}
			
			processArgsContainer(argsContainer);

			List<String> argsList = new ArrayList<String>(Arrays.asList(args));

			argsList.addAll(Arrays.asList(new String[] { "-w",
					"-keep-line-number", "-main-class", runClass, runClass }));
			InitialClasses();

			PathTransform transform = new PathTransform(files, startClass,
					startLine, endClass, endLine);

			PackManager.v().getPack("wjtp").add(
					new Transform("wjtp.myTrans", transform));
			args = argsList.toArray(new String[0]);
			
			// To see the arguments...
			for (int i = 0; i < args.length; i++) {
				System.out.println(args[i]);
			}
			System.out.println(files.toString());
			// Soot Main
			soot.Main.main(args);
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
	}

	private static void processArgsContainer(Vector<String> argsContainer) {
		runClass = argsContainer.get(0);
		String[] start = argsContainer.get(1).split(":");
		String[] end = argsContainer.get(2).split(":");
		if ((start.length != 2) || (end.length != 2)) {
			System.err.println("args formate error");
			System.exit(0);
		}
		startClass = start[0];
		startLine = start[1];
		endClass = end[0];
		endLine = end[1];
	}

	private static void InitialClasses() {
		files = new Vector<String>();
		// File root = new File("D:\\Projects\\JtopasV2\\bin");
		// File root = new File("D:\\Projects\\StaticPathGenerator\\bin\\test");
//		File root = new File("D:\\Projects\\antlr-2.7.2\\bin");
		File root = new File(DirectoryUtil.SUBJECT_CLASS_FOLDER);
		travel(root);
	}

	private static void travel(File root) {
		if (root.isDirectory()) {
			File[] children = root.listFiles();
			if (children.length != 0) {
				for (int i = 0; i < children.length; i++) {
					travel(children[i]);
				}
			}
		} else {
			if (root.getName().endsWith(".class")) {
				String name = null;
				String rootPath = root.getPath();
				
				if(File.separator.equals("\\")){
					name = rootPath.replaceAll("\\\\", "."); // Windows style file separator
				}else if(File.separator.equals("/")){
					name = rootPath.replaceAll("/", "."); // Linux style file separator
				}else{
					// Unknown file separator...
					System.err.println("Unknown file separator.");
				}
				
				// String name = root.getPath().replaceAll("\\\\", ".");  
				// String name = root.getPath().replaceAll("/", "."); 
				
				// files.add(name);
				String dirSeg = DirectoryUtil.SUBJECT_CLASS_FOLDER_SEGMENT;
				// FIXME: this can be faulty when there are substrings that are identical to 'dirSeg'
				// in the full file path.
				files.add( name.substring(name.indexOf(dirSeg) + dirSeg.length() + 1, 
						                  name.lastIndexOf('.'))
						  );
				
			}
		}
	}
}
